package sokoban;

import java.util.Vector;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.List;
import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class Sokoban extends MIDlet implements CommandListener {

	private SokobanCanvas canvas;

	private MenuCanvas menu;

	private NetMapLoader recordStoreLoader;

	private NetMapLoader netLoader;

	private Vector gameMaps;

	private Display display;

	private Command pauseCommand;

	private Command cancelCommand;

	private Command restartCommand;

	private Command getMapCommand;

	private Command startCommand;

	private Command continueCommand;

	private Command fullScreenCommand;

	private Command selectLevelCommand;

	private Command loadMapCommand;

	private Command exitCommand;

	private List levelList;

	private TextBox addressBox;

	private boolean fullscreen = false;

	private void initObjects() {

		canvas = new SokobanCanvas();

		menu = new MenuCanvas();

		recordStoreLoader = new NetMapLoader(this);

		netLoader = new NetMapLoader(this);

		gameMaps = new Vector();

		pauseCommand = new Command("Pause", Command.ITEM, 6);

		cancelCommand = new Command("Cancel", Command.CANCEL, 1);

		restartCommand = new Command("Restart", Command.ITEM, 2);

		getMapCommand = new Command("Load map", Command.ITEM, 3);

		startCommand = new Command("New game", Command.ITEM, 2);

		continueCommand = new Command("Continue", Command.ITEM, 2);

		fullScreenCommand = new Command("Full screen on / off", Command.ITEM, 4);

		selectLevelCommand = new Command("Select level", Command.ITEM, 3);

		loadMapCommand = new Command("Load", Command.OK, 1);

		levelList = new List("Select level", List.IMPLICIT);

		exitCommand = new Command("Exit", Command.ITEM, 9);

		addressBox = new TextBox("Address",
				"http://staff.cs.utu.fi/opinnot/kurssit/mobo/06/J2ME/", 256,
				TextField.ANY);

		display = Display.getDisplay(this);
	}

	public Sokoban() {
		initObjects();
		canvas.addCommand(restartCommand);
		canvas.addCommand(fullScreenCommand);
		canvas.addCommand(selectLevelCommand);
		canvas.addCommand(pauseCommand);
		canvas.addCommand(exitCommand);
		canvas.setFullScreenMode(false);
		menu.addCommand(getMapCommand);
		menu.addCommand(fullScreenCommand);
		menu.addCommand(exitCommand);
		menu.setFullScreenMode(false);
		addressBox.addCommand(loadMapCommand);
		addressBox.addCommand(cancelCommand);
		canvas.setCommandListener(this);
		menu.setCommandListener(this);
		levelList.setCommandListener(this);
		addressBox.setCommandListener(this);
		recordStoreLoader.loadFromRecordStore();
		display.setCurrent(menu);
	}

	protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
		if (canvas != null) {
			canvas.stop();
		}
	}

	protected void pauseApp() {
		if (canvas != null) {
			canvas.stop();
		}
	}

	protected void startApp() throws MIDletStateChangeException {
		if (canvas != null) {
			canvas.start();
		}
	}

	private void startGame() {
		GameMap g = (GameMap)gameMaps.elementAt(0));
		g.reset();
		canvas.setGameMap(g);
		display.setCurrent(canvas);
		canvas.start();
	}

	public void commandAction(Command cmd, Displayable disp) {
		if (cmd == startCommand) {
			startGame();
		} else if (cmd == fullScreenCommand) {
			fullscreen = !fullscreen;
			if (fullscreen) {
				menu.setFullScreenMode(true);
				canvas.setFullScreenMode(true);
			} else {
				menu.setFullScreenMode(false);
				canvas.setFullScreenMode(false);
			}
		} else if (cmd == selectLevelCommand) {
			display.setCurrent(levelList);
		} else if (cmd == List.SELECT_COMMAND) {
			canvas.setGameMap((GameMap) gameMaps.elementAt(levelList
					.getSelectedIndex()));
			canvas.getGameMap().reset();
			display.setCurrent(canvas);
		} else if (cmd == restartCommand) {
			canvas.getGameMap().reset();
		} else if (cmd == getMapCommand) {
			display.setCurrent(addressBox);
		} else if (cmd == loadMapCommand) {
			display.setCurrent(menu);
			netLoader.loadFromNet(addressBox.getString());
		} else if (cmd == cancelCommand) {
			display.setCurrent(menu);
		} else if (cmd == continueCommand) {
			canvas.removeCommand(continueCommand);
			menu.removeCommand(continueCommand);
			display.setCurrent(canvas);
			canvas.start();
		} else if (cmd == pauseCommand) {
			menu.addCommand(continueCommand);
			display.setCurrent(menu);
			canvas.stop();
		} else if (cmd == exitCommand) {
			canvas.stop();
			notifyDestroyed();
		}
	}

	public void addGameMap(GameMap gameMap) {
		if (gameMaps.size() == 0) {
			menu.addCommand(startCommand);
		}
		gameMaps.addElement(gameMap);
		levelList.append(gameMap.getTitle(), null);
	}

	public void showInfo(String s) {
		Alert a = new Alert("Info", s, null, AlertType.INFO);
		display.setCurrent(a, display.getCurrent());
	}
}